using System;
using System.Windows.Forms;
using NUnit.Framework;
using NUnit.Extensions.Forms;
using Microsoft.VSPowerToys.PackInstaller;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Diagnostics;
using GUITestScenarios;

namespace PackInstallerLicenseFormTests
{
    [TestFixture]
    public class PackInstallerLicenseTests : NUnitFormTest
    {

        #region Private Data and Methods
        private PackInstallerForm packInstallForm;
        private ErrorMessages errorMessages;

        /// <summary>
        /// In order to test forms with ShowDialog under NUnitForms, you have to
        /// provide a "handler" method for the Form. Normally, this handler would
        /// contain the test logic. But, that doesn't work well for the PackInstaller
        /// because it uses threads. 
        /// 
        /// So, the test logic will be in a delegate method attched to the PackInstaller 
        /// form. Therefore, this is a skeleton handler and used for most tests.
        /// </summary>
        private void GenericFormHandler()
        {
            packInstallForm.Close();
        }
        #endregion

        [TestFixtureSetUp]
        public void FixtureSetup()
        {
            Process[] visualStudioProcesses = Process.GetProcessesByName("devenv");
            TextWriter errorWriter = Console.Error;
            if (visualStudioProcesses.Length != 0)
            {
                errorWriter.WriteLine("You must close Visual Studio before running the test suite.");
                Assert.IsTrue(false);
            }
        }

        #region Click Decline License Button
        /// <summary>
        /// This test clicks the I Decline button on the license agreement form
        /// Verifies that the Pack Installer exits when the user declines the license 
        /// </summary>
        [Test]
        public void DeclinePackInstallerLicenseTest()
        {
            errorMessages = new ErrorMessages();
            PackInstallerLicenseAgreementForm.ResetLastLicenseAcceptedSetting();
            packInstallForm = new PackInstallerForm(@"..\..\GeneralTestPackFeed.xml");
            ExpectModal("PackInstallerForm", "GenericFormHandler");
            ExpectModal("PackInstallerLicenseAgreementForm", "DeclineLicenseFormHandler");
            packInstallForm.ShowDialog();
            errorMessages.printErrors("DeclinePackInstallerLicenseTest");
            Assert.AreEqual(0, errorMessages.Count, "DeclinePackInstallerLicenseTest failed. Check Console output for error messages.");
        }

        private void DeclineLicenseFormHandler()
        {
            ButtonTester buttonTester = new ButtonTester("declineButton", "PackInstallerLicenseAgreementForm");
            FormTester ft = new FormTester("PackInstallerLicenseAgreementForm");

            // Verify that the decline button has been selected
            if (ft.Properties.ActiveControl == null)
                errorMessages.Add("Active control is null");
            else if (ft.Properties.ActiveControl.Name != "declineButton")
                errorMessages.Add("Active control is " + ft.Properties.ActiveControl.Name + " instead of declineButton");

            // Check the text of the decline button
            if (buttonTester.Text != "I &Decline")
            {
                errorMessages.Add("License Form decline button text is wrong '" + buttonTester.Text + "'");
            }
            buttonTester.Click();
        }
        #endregion

        #region Click Form's Accept Button
        /// <summary>
        /// This test clicks the Form's Accept button which is the same as 
        /// clicking Enter.
        /// This test along with the ClickEscapeOnLicenseFormTest verifies 
        /// the test plan's License Terms Dialog scenario #2
        /// </summary>
        [Test]
        public void EnterClickOnPackInstallerLicenseFormTest()
        {
            errorMessages = new ErrorMessages();
            PackInstallerLicenseAgreementForm.ResetLastLicenseAcceptedSetting();
            packInstallForm = new PackInstallerForm(@"..\..\GeneralTestPackFeed.xml");
            ExpectModal("PackInstallerForm", "GenericFormHandler");
            ExpectModal("PackInstallerLicenseAgreementForm", "ClickEnterLicenseFormHandler");
            packInstallForm.ShowDialog();
            errorMessages.printErrors("ClickEnterOnPackInstallerLicenseFormTest");
            Assert.AreEqual(0, errorMessages.Count, "ClickEnterOnPackInstallerLicenseFormTest failed. Check Console output for error messages.");
        }

        private void ClickEnterLicenseFormHandler()
        {
            FormTester formTester = new FormTester("PackInstallerLicenseAgreementForm");
            if (formTester.Properties.AcceptButton != null)
            {
                formTester.Properties.AcceptButton.PerformClick();
            }
            else
            {
                errorMessages.Add("ClickEnterLicenseFormHandler: PackInstallerLicenseAgreementForm AcceptButton was not found.");
                ButtonTester buttonTester = new ButtonTester("declineButton", "PackInstallerLicenseAgreementForm");
                buttonTester.Click();
            }
        }
        #endregion

        #region Clicks  Form's Cancel Button
        /// <summary>
        /// This test clicks the Form's Cancel button which is the same as 
        /// clicking Enter.
        /// This test along with the ClickEnterOnLicenseFormTest verifies 
        /// the test plan's License Terms Dialog scenario #2
        /// </summary>
        [Test]
        public void EscapeClickOnPackInstallerLicenseFormTest()
        {
            errorMessages = new ErrorMessages();
            PackInstallerLicenseAgreementForm.ResetLastLicenseAcceptedSetting();
            packInstallForm = new PackInstallerForm(@"..\..\GeneralTestPackFeed.xml");
            ExpectModal("PackInstallerForm", "GenericFormHandler");
            ExpectModal("PackInstallerLicenseAgreementForm", "ClickEscapeLicenseFormHandler");
            packInstallForm.ShowDialog();
            errorMessages.printErrors("ClickEscapeOnPackInstallerLicenseFormTest");
            Assert.AreEqual(0, errorMessages.Count, "ClickEscapeOnPackInstallerLicenseFormTest failed. Check Console output for error messages.");
        }

        public void ClickEscapeLicenseFormHandler()
        {
            FormTester formTester = new FormTester("PackInstallerLicenseAgreementForm");
            if (formTester.Properties.CancelButton != null)
            {
                formTester.Properties.CancelButton.PerformClick();
            }
            else
            {
                errorMessages.Add("ClickEnterLicenseFormHandler: PackInstallerLicenseAgreementForm CancelButton was not found.");
                ButtonTester buttonTester = new ButtonTester("declineButton", "PackInstallerLicenseAgreementForm");
                buttonTester.Click();
            }
        }
        #endregion

        #region Close License Form
        /// <summary>
        /// Verifies that closing the form declines the license
        /// </summary>
        [Test]
        public void PackInstallerLicenseFormCloseTest()
        {
            errorMessages = new ErrorMessages();
            PackInstallerLicenseAgreementForm.ResetLastLicenseAcceptedSetting();
            packInstallForm = new PackInstallerForm(@"..\..\GeneralTestPackFeed.xml");
            ExpectModal("PackInstallerForm", "GenericFormHandler");
            ExpectModal("PackInstallerLicenseAgreementForm", "CloseLicenseFormHandler");
            packInstallForm.ShowDialog();
            errorMessages.printErrors("CloseLicenseFormTest");
            Assert.AreEqual(0, errorMessages.Count, "CloseLicenseFormTest failed. Check Console output for error messages.");
        }
        public void CloseLicenseFormHandler()
        {
            FormTester tester = new FormTester("PackInstallerLicenseAgreementForm");
            tester.Close();
        }
        #endregion

        #region Accept the license agreement
        /// <summary>
        /// Verifies that Pack Installer presents the license agreement if it has not been previous accepted
        /// </summary>
        [Test]
        public void PackInstallerLicenseFormLicenseAcceptTest()
        {
            errorMessages = new ErrorMessages();
            PackInstallerLicenseAgreementForm.ResetLastLicenseAcceptedSetting();
            packInstallForm = new PackInstallerForm(@"..\..\GeneralTestPackFeed.xml");
            ExpectModal("PackInstallerForm", "GenericFormHandler");
            ExpectModal("PackInstallerLicenseAgreementForm", "AcceptLicenseFormHandler");
            packInstallForm.ShowDialog();
            errorMessages.printErrors("PackInstallerLicenseFormLicenseAcceptTest");
            Assert.AreEqual(0, errorMessages.Count, "PackInstallerLicenseFormLicenseAcceptTest failed. Check Console output for error messages.");
        }

        private void AcceptLicenseFormHandler()
        {
            ButtonTester buttonTester = new ButtonTester("acceptButton", "PackInstallerLicenseAgreementForm");
            FormTester ft = new FormTester("PackInstallerLicenseAgreementForm");

            // Check the text of the decline button
            if (buttonTester.Text != "I &Accept")
            {
                errorMessages.Add("License Form accept button text is wrong '" + buttonTester.Text + "'");
            }
            buttonTester.Click();
        }

        /// <summary>
        /// Verifies that the Pack Installer does not present a license agreement form after it has been accepted.
        /// </summary>
        [Test]
        public void PostPackInstallerLicenseFormLicenseAcceptTest()
        {
            errorMessages = new ErrorMessages();
            packInstallForm = new PackInstallerForm(@"..\..\GeneralTestPackFeed.xml");
            ExpectModal("PackInstallerForm", "GenericFormHandler");
            packInstallForm.ShowDialog();
            errorMessages.printErrors("PostPackInstallerLicenseFormLicenseAcceptTest");
            Assert.AreEqual(0, errorMessages.Count, "PostPackInstallerLicenseFormLicenseAcceptTest failed. Check Console output for error messages.");
        }
        #endregion
    }
}
